home *** CD-ROM | disk | FTP | other *** search
/ Collection of Internet / Collection of Internet.iso / infosrvr / dev / libhtml_.tar / HMDoc.c < prev    next >
C/C++ Source or Header  |  1993-01-21  |  4KB  |  252 lines

  1. /* HMDoc.c -- HyperMedia Document base class
  2.  */
  3.  
  4. /* implements ... */
  5. #include "HMDoc.h"
  6.  
  7. /* uses ... */
  8. #include "HTMLdtd.h"
  9. #include "SGML.h"
  10. #include "object.h"
  11.  
  12. static HMFileWriterProc fileWriter;
  13. static HMWriterProc writer;
  14. static HMDeleteProc delete;
  15. static HMStartTagProc startTag;
  16. static HMEndTagProc endTag;
  17. static HMDataProc data;
  18.  
  19. HMDoc_Class InCore = {fileWriter, writer,
  20.             delete,
  21.             startTag, endTag, data,
  22.             html_entity_text};
  23.  
  24. typedef struct{
  25.   char* gi;
  26.   int content;
  27.   int nattrs;
  28.   HMBinding* attrs;
  29. }Tag;
  30.  
  31. typedef struct _cell{
  32.   struct _cell *first, *rest, *up;
  33. }Cons;
  34.  
  35. struct _HMDoc{
  36.   Cons* root;
  37.   Cons* here;
  38. };
  39.  
  40.  
  41. /* constructors */
  42.  
  43. static HMDoc*
  44.   fileWriter(fp)
  45. FILE* fp;
  46. {
  47.   return 0; /* this class doesn't write to files */
  48. }
  49.  
  50. static HMDoc*
  51.   writer(out, write)
  52. HMStream out;
  53. HMWriteProc* write;
  54. {
  55.   return 0; /* this class doesn't write to streams */
  56. }
  57.  
  58. HMDoc*
  59.   InCore_new()
  60. {
  61.   HMDoc* this = NEW(HMDoc, 1);
  62.   this->root = 0;
  63.   this->here = 0;
  64.   return this;
  65. }
  66.  
  67. /* destructors */
  68.  
  69. static VOID Tag_free PARAMS((Tag* it));
  70.  
  71. static VOID
  72.   element_free(this)
  73. Cons* this;
  74. {
  75.   Cons* c;
  76.  
  77.   if(this->first){
  78.     Cons* next;
  79.     Tag_free((Tag*)this->first);
  80.     for(c = this->rest; c; c = next){
  81.       element_free(c->first);
  82.       next = c->rest;
  83.       FREE(c);
  84.     }
  85.   }else{
  86.     FREE(this->rest); /* data */
  87.   }
  88.   FREE(this);
  89. }
  90.  
  91.  
  92. static VOID
  93.   delete(this)
  94. HMDoc* this;
  95. {
  96.   if(this->root)
  97.     element_free(this->root);
  98. }
  99.  
  100.  
  101.  
  102. /* building routines */
  103.  
  104. static Tag*
  105.   Tag_new(gi, content, attrs, nattrs)
  106. CONST char* gi;
  107. CONST HMBinding attrs[];
  108. int nattrs;
  109. {
  110.   Tag* this = NEW(Tag, 1);
  111.   int total = strlen(gi) + 1;
  112.   int i;
  113.   char* p;
  114.  
  115.   for(i = 0; i<nattrs; i++)
  116.     total += strlen(attrs[i].name) + 1
  117.       + strlen(attrs[i].value) + 1;
  118.  
  119.   this->gi = NEW(char, total);
  120.   this->content = content;
  121.   this->attrs = NEW(HMBinding, nattrs);
  122.   this->nattrs = nattrs;
  123.  
  124.   strcpy(this->gi, gi);
  125.   p = this->gi;
  126.   while(*p++);
  127.  
  128.   for(i=0; i<nattrs; i++){
  129.     strcpy(this->attrs[i].name = p, attrs[i].name);
  130.     while(*p++);
  131.     strcpy(this->attrs[i].value = p, attrs[i].value);
  132.     while(*p++);
  133.   }
  134.   return this;
  135. }
  136.  
  137. static VOID
  138.   Tag_free(this)
  139. Tag* this;
  140. {
  141.   FREE(this->gi);
  142.   FREE(this->attrs);
  143. }
  144.  
  145.  
  146. static Cons*
  147.   cons(car, cdr, parent)
  148. VOIDPTR car;
  149. VOIDPTR cdr;
  150. Cons* parent;
  151. {
  152.   Cons* this = NEW(Cons, 1);
  153.   this->first = (Cons*)car;
  154.   this->rest = (Cons*)cdr;
  155.   this->up = parent;
  156.   return this;
  157. }
  158.  
  159.  
  160. static VOID
  161.   attach(this, element, data)
  162. HMDoc* this;
  163. Tag* element;
  164. CONST char* data;
  165. {
  166.   Cons* it = cons(element, data);
  167.  
  168.   if(this->here){
  169.     Cons* cell = cons(it, 0, this->here->up);
  170.     this->here->rest = cell;
  171.     this->here = cell;
  172.   }else{
  173.     this->root = this->here = it;
  174.   }
  175. }
  176.  
  177.  
  178. static int
  179.   startTag(this, gi, attributes, nattrs)
  180. HMDoc* this;
  181. CONST char* gi;
  182. CONST HMBinding attributes[];
  183. int nattrs;
  184. {
  185.   int c = HTML_content(gi);
  186.   Tag* nt = Tag_new(gi, c, attributes, nattrs); /* content? @@*/
  187.  
  188.   attach(this, nt, 0);
  189.  
  190.   return c;
  191. }
  192.  
  193.  
  194. static VOID
  195.   endTag(this, gi)
  196. HMDoc* this;
  197. CONST char* gi;
  198. {
  199.   if(this->here && this->here->up)
  200.     this->here = this->here->up;
  201. }
  202.  
  203.  
  204. static VOID
  205.   data(this, data, qty)
  206. HMDoc* this;
  207. CONST char* data;
  208. int qty;
  209. {
  210.   if(this->here){
  211.     char* nd = NEW(char, qty+sizeof(int));
  212.     *((int*)nd) = qty;
  213.     memcpy(nd + sizeof(int), data, qty);
  214.     attach(this, 0, nd);
  215.   }
  216. }
  217.  
  218.  
  219. /* traverse the document */
  220.  
  221. static VOID
  222.   element_traverse(this, dest, docclass)
  223. Cons* this;
  224. HMDoc* dest;
  225. HMDoc_Class* docclass;
  226. {
  227.   Cons* c;
  228.  
  229.   if(this->first){
  230.     Tag* t = (Tag*)(this->first);
  231.     (docclass->startTag)(dest, t->gi, t->attrs, t->nattrs);
  232.     if(t->content != SGML_EMPTY){
  233.       for(c = this->rest; c; c = c->rest)
  234.     element_traverse(c->first, dest, docclass);
  235.       (docclass->endTag)(dest, t->gi);
  236.     }
  237.   }else{
  238.     int q = *((int*)(this->rest));
  239.     char* d = ((char*)(this->rest)) + sizeof(int);
  240.     (docclass->data)(dest, d, q);
  241.   }
  242. }
  243.  
  244. VOID
  245. InCore_traverse(this, that, c)
  246.      HMDoc* this;
  247.      HMDoc* that;
  248.      HMDoc_Class* c;
  249. {
  250.   element_traverse(this->root, that, c);
  251. }
  252.